# -*- coding: utf-8 -*-
import time
import pyautogui
from pynput.keyboard import Key, Controller, Listener
import win32api, win32gui, win32con
from pynput import mouse
#from PIL import Image
import numpy as np
from paddleocr import PaddleOCR, draw_ocr
import logging

logging.disable(logging.DEBUG)  # 关闭DEBUG日志的打印
logging.disable(logging.WARNING)  # 关闭WARNING日志的打印

keyboard = Controller()
# 通用步骤变量
tableDataListenWndSize = None  # 数据监控窗口区域大小（x,y,width,height）
buttonDataListenWndSize = None  # 数据监控窗口区域大小（x,y,width,height）
kill = False  # 退出程序阻塞，默认否一直监听
ordButtonType = 0  # 订单（1买、2卖、3平仓）操作类型
# 业务步骤：1 录入合约代码（enter继续） 2 录入该合约的价差（+-两位小数）
symbolCode = None
symbolPriceOffSet = 0.00  # 合约价差点位
symbolPriceMarket = 0.00  # 市场最新价
symbolPriceCus = 0.00  # 自定义金额
tableCursorPos = None  # 数据窗口鼠标点位
ordButtonCursorPos = None  # 操作按钮鼠标点位
bizStep = 0  # 程序步骤 1 设置表格数据窗口 2 设置订单操作窗口 3 设置合约 4 执行数据组自动化操作
inputDesc = ''  # 录入提示操作文本
descText = '''
执行流程和说明：
注意：1、请提前调整好应用窗口，左上角对齐屏幕，确保窗口可见数据窗口（）及操作窗口（买、卖、平台）按钮且无遮挡。2、设置好后不要改变窗口大小及位置，否则需要重启本工具
通用步骤（回车生效）：1 设置表格数据窗口（鼠标移入并enter继续） 2 设置订单（1买、2卖、3平仓）操作窗口（鼠标移入并enter继续）
业务步骤（回车生效）：1 录入合约代码（enter继续） 2 录入该合约的价差（+-两位小数）
'''

keyboard_key_dict = {
    r"'\x01'": ['ctrl', 'a'],
    r"'\x02'": ['ctrl', 'b'],
    r"'\x03'": ['ctrl', 'c'],
    r"'\x04'": ['ctrl', 'd'],
    r"'\x05'": ['ctrl', 'e'],
    r"'\x06'": ['ctrl', 'f'],
    r"'\x07'": ['ctrl', 'g'],
    r"'\x08'": ['ctrl', 'h'],
    r"'\t'": ['ctrl', 'i'],
    r"'\n'": ['ctrl', 'j'],
    r"'\x0b'": ['ctrl', 'k'],
    r"'\x0c'": ['ctrl', 'l'],
    r"'\r'": ['ctrl', 'm'],
    r"'\x0e'": ['ctrl', 'n'],
    r"'\x0f'": ['ctrl', 'o'],
    r"'\x10'": ['ctrl', 'p'],
    r"'\x11'": ['ctrl', 'q'],
    r"'\x12'": ['ctrl', 'r'],
    r"'\x13'": ['ctrl', 's'],
    r"'\x14'": ['ctrl', 't'],
    r"'\x15'": ['ctrl', 'u'],
    r"'\x16'": ['ctrl', 'v'],
    r"'\x17'": ['ctrl', 'w'],
    r"'\x18'": ['ctrl', 'x'],
    r"'\x19'": ['ctrl', 'y'],
    r"'\x1a'": ['ctrl', 'z'],
    r"'\x1f'": ['ctrl', 'shift', '-'],
    r"<186>": ['ctrl', ';'],
    r"<187>": ['ctrl', '='],
    r"<189>": ['ctrl', '-'],
    r"<192>": ['ctrl', '`'],
    r"<222>": ['ctrl', r"'"],
    r"<48>": ['ctrl', '0'],
    r"<49>": ['ctrl', '1'],
    r"<50>": ['ctrl', '2'],
    r"<51>": ['ctrl', '3'],
    r"<52>": ['ctrl', '4'],
    r"<53>": ['ctrl', '5'],
    r"<54>": ['ctrl', '6'],
    r"<55>": ['ctrl', '7'],
    r"<56>": ['ctrl', '8'],
    r"<57>": ['ctrl', '9'],
    r"'~'": ['shift', '`'],
    r"'!'": ['shift', '1'],
    r"'@'": ['shift', '2'],
    r"'#'": ['shift', '3'],
    r"'$'": ['shift', '4'],
    r"'%'": ['shift', '5'],
    r"'^'": ['shift', '6'],
    r"'*'": ['shift', '7'],
    r"'('": ['shift', '8'],
    r"')'": ['shift', '9'],
    r"'_'": ['shift', '-'],
    r"'+'": ['shift', '='],
    r"':'": ['shift', ';'],
    r"'\"'": ['shift', "'"],
    r"'<'": ['shift', ","],
    r"'{'": ['shift', "["],
    r"'}'": ['shift', "]"],
    r"'|'": ['shift', "\\"],
    r"'?'": ['shift', "/"],
}


###
# try:
#
#     time.sleep(2)
#
#     point = win32api.GetCursorPos()  # win32api.GetCursorPos 获取鼠标当前的坐标(x,y)
#
#     handle = win32gui.WindowFromPoint(point)  # 查看坐标位置窗口的句柄
#
#    # print(handle)  # 输出句柄
#
#     # 获取窗口句柄
#     #handle = win32gui.WindowFromPoint((24, 52))
#     print("窗口句柄是：{}".format(handle))
#
#     # 获取窗口信息 （x,y坐标，还有宽度，高度）
#     handleMessage = win32gui.GetWindowRect(handle)#通过窗口句柄获取窗口信息
#     print("窗口 x,y坐标，还有宽度，高度是：{}".format(handleMessage))
#
#     # 指定局部区域
#     box = handleMessage
#     im = pyautogui.screenshot()
#     # 使用crop函数进行裁切
#     img = im.crop(box)
#
#     img.show()  # 展示当前图片
#     # 获取窗口标题
#     title = win32gui.GetWindowText(handle)
#     print("窗口标题是：{}".format(title))
#     # 获取窗口类名
#     class_name = win32gui.GetClassName(handle)
#     print("窗口类名是：{}".format(class_name))
# except Exception as e:
#     print("窗口句柄获取失败：{}".format(e))

def on_click(x, y, button, pressed):
    if kill:
        m_listener.stop()
    global bizStep
    #print(f"当前步骤：{bizStep}")
    if pressed:
        print('鼠标按下：{0} 在 ({1}, {2})'.format(button, x, y))
        if bizStep == 1:
            tableCursorPos = (x, y)  # win32api.GetCursorPos 获取鼠标当前的坐标(x,y)
            wnd = win32gui.WindowFromPoint(tableCursorPos)  # 查看坐标位置窗口的句柄
            tableDataListenWndSize = win32gui.GetWindowRect(wnd)
            img = pyautogui.screenshot(region=tableDataListenWndSize)
            img.save("ttt.jpg")
            bizStep = 2
    else:
        print('鼠标释放：{0} 在 ({1}, {2})'.format(button, x, y))
        m_listener.stop()


def on_press_biz(key):
    global bizStep, img, kill, tableDataListenWndSize, symbolCode, symbolPriceOffSet, symbolPriceMarket, ordButtonCursorPos
    #print(f"当前步骤：{str(bizStep)}")
    if key == Key.esc or bizStep == 5 or key == 'p':  # 人为操作退出
        print("终止程序！")
        kill = True
        k_listener.stop()
    # elif key == Key.enter:
    elif str(key) == r"'\x04'":  # ctrl+d
        if key == Key.esc or bizStep == 5:  # 人为操作退出
            print("终止程序！")
            kill = True
            k_listener.stop()
        if bizStep == 0:
            print("设置表格数据窗口（鼠标移动到黑色空白区域，ctrl+d继续）：")
            bizStep = 1
        # 按下组合按键：ctrl + q 切换鼠标事件
        # keyboard.press(Key.ctrl)
        # keyboard.press("q")
        elif bizStep == 1:
            tableCursorPos = win32api.GetCursorPos()  # 获取鼠标当前的坐标(x,y)
            wnd = win32gui.WindowFromPoint(tableCursorPos)  # 查看坐标位置窗口的句柄
            tableDataListenWndSize = win32gui.GetWindowRect(wnd)
            img = pyautogui.screenshot(region=tableDataListenWndSize)
            img.save(f"{wnd}-{bizStep}.png")
            # result = p_ocr(np.array(img))
            print("完成设置表格数据窗口")
            print("设置订单按钮操作，先鼠标移入位置后(1买,2卖,3平仓),ctrl+d继续:")
            # time.sleep(1)
            # ordButtonType = int(input("设置订单按钮操作，鼠标移入位置后请输入数字：1买,2卖,3平仓,回车enter继续:"))
            # while ordButtonType < 1 or ordButtonType > 3:
            #     ordButtonType = int(
            #         input("数据范围须>=1或<=3;设置订单按钮操作，鼠标移入位置后请输入数字：1买,2卖,3平仓,回车enter继续:"))
            # print(f"完成设置订单按钮操作（1买,2卖,3平仓）为:{str(ordButtonType)},ctrl+d继续")
            bizStep = 2
        elif bizStep == 2:
            ordButtonCursorPos = win32api.GetCursorPos()  # 获取鼠标当前的坐标(x,y)
            wnd = win32gui.WindowFromPoint(ordButtonCursorPos)  # 查看坐标位置窗口的句柄
            buttonDataListenWndSize = win32gui.GetWindowRect(wnd)
            # img = pyautogui.screenshot(region=buttonDataListenWndSize)
            # img.save(f"{wnd}-{bizStep}.png")
            print("完成设置订单操作窗口位置")
            symbolCode = str(input("录入合约代码,回车enter继续:"))
            print(f"完成录入合约代码为：{symbolCode}")
            symbolPriceOffSet = float(input("录入合约价差点位,回车enter继续:"))  # 合约价差点位
            print(
                f"完成录入合约代码:{symbolCode},价差点位:{str(symbolPriceOffSet)},ctrl+d继续:")
            bizStep = 3
        elif bizStep == 3:
            print("初始化数据处理中...")
            start_time = time.time()  # 记录开始时间
            # 这里写需要测试性能的代码段
            img = pyautogui.screenshot(region=tableDataListenWndSize)
            result = p_ocr(np.array(img))
            try:
                index = result.index(symbolCode)
                print(f'{symbolCode}位于索引{format(index)}处')
                symbolPriceMarket = result[index + 2]
                print(f'{symbolCode}:市场最新价格为：{str(symbolPriceMarket)}')
            except ValueError:
                print(f"{symbolCode}不在数组中")

            end_time = time.time()  # 记录结束时间
            execution_time = end_time - start_time  # 计算程序运行时间（单位为秒）
            print(f"完成初始化数据处理时间：{str(execution_time)}")
            print("esc键则退出；先鼠标点击激活监听的窗口，ctrl+d启动操作（1买,2卖,3平仓）继续？:")
            bizStep = 4
        elif bizStep == 4:
            # 设置鼠标位置
            win32api.SetCursorPos(ordButtonCursorPos)
            # 模拟鼠标左键单击
            win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
            win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
            time.sleep(0.5)
            # 确认订单操作
            keyboard.press(Key.enter)


            return True
            # 监听ocr捕获表格数据
            while Key.name != 'p' and bizStep != 5:
                time.sleep(0.2)
                img = pyautogui.screenshot(region=tableDataListenWndSize)
                img.save(f"ord{bizStep}.png")
                result = p_ocr(np.array(img))
                print(result)
                index = result.index(symbolCode)
                if index != -1:
                    nowProice = result[index + 2]
                    price = symbolPriceMarket + symbolPriceOffSet
                    if nowProice <= price:
                        # 订单操作
                        # 设置鼠标位置
                        win32api.SetCursorPos(ordButtonCursorPos)
                        # 模拟鼠标左键单击
                        win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
                        win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
                        time.sleep(0.2)
                        # 确认订单操作
                        keyboard.press(Key.enter)
                        bizStep = 5
                    print(f'合约代码为:{symbolCode},最新价格为：{str(nowProice)}')
            runType = str(input("已完成订单操作,重新运行y,退出n (默认退出)，输入y/n 回车enter继续:")).lower()
            if not runType or runType == 'n':
                print("终止程序！")
                kill = True
                k_listener.stop()
                bizStep = 5
            else:
                while runType != 'n' or runType != 'y':
                    runType = str(input("输入错误,重新运行或退出y/n(默认退出)，回车enter继续:")).lower()
                print("终止程序！")
                kill = True
                k_listener.stop()
                bizStep = 5
            if runType == 'y':
                bizStep = 4
                # 执行
                keyboard.press(Key.enter)
    elif str(key) == r"'\x11'":  # 按下组合按键：ctrl + q
        print("触发ctrl+q,开始监听鼠标事件,点击鼠标继续:")
        k_listener.stop()
    # print('按键： {} 被按下'.format(key))


def on_release(key):
    print('{} 释放了'.format(key))
    if key == keyboard.Key.esc:
        # 释放了esc 键，停止监听
        return False


def get_curtime(time_format="%Y-%m-%d %H:%M:%S"):
    curTime = time.localtime()
    curTime = time.strftime(time_format, curTime)
    return curTime



def p_ocr(img):
    ocr = PaddleOCR(use_angle_cls=True, lang="ch")
    result = ocr.ocr(img, cls=True)
    # ocr识别结果文字
    ocr_content = []
    for line in result:
        # content = []
        for tmpTwo in line:
            # print("tmpTwo:")
            # print(tmpTwo)
            for tmpThree in tmpTwo:
                # print("tmpThree:")
                # print(tmpThree)
                finalArr = str(tmpThree).split(",")
                finalStr = finalArr[0].replace("'", "").replace("(", "")
                # print("finalStr:" + finalStr)
                if finalStr.find("[") < 0:
                    ocr_content.append(finalStr)
    # print("ocr_content:")
    print(ocr_content)
    return ocr_content

if __name__ == '__main__':
    # global bizStep, inputDesc, tableDataListenWndSize, buttonDataListenWndSize, kill, ordButtonType, symbolCode, symbolPriceOffSet, tableCursorPos, ordButtonCursorPos, bizStep, inputDesc, descText ,img
    # keyboard.add_hotkey('ctrl', test_b, args=('1',))  # 通过快捷键触发执行函数
   # print(descText)
    print("esc退出,ctrl+q切换鼠标事件,其他按提示操作;ctrl+d继续:")
    # keyboard.add_hotkey('enter', excuteBiz)  # 通过快捷键触发执行函数
    # keyboard.add_hotkey('ctrl+1', on_press)  # 通过快捷键触发执行函数
    # keyboard.wait("esc")  # 循环监听
    while not kill:
        with Listener(on_press=on_press_biz, on_release=None) as k_listener:
            k_listener.join()
        if not kill:
            with mouse.Listener(on_click=on_click) as m_listener:
                m_listener.join()
    # recorded = keyboard.record(until='esc')
